﻿Public Class FileMng_UTIni
    Inherits FileMng

    Public Property listTestSuites As List(Of TestSuite)
    Public Property intVerbose As Integer
    Public Property strProjectName As String

    Public Sub New(ByVal inVerbose As Integer, ByVal inProjectName As String)
        intVerbose = inVerbose
        strProjectName = inProjectName
        listTestSuites = New List(Of TestSuite)
    End Sub

    Public Sub New()
        intVerbose = 0
        strProjectName = ""
        listTestSuites = New List(Of TestSuite)
    End Sub

#Region "Utility"

    Private Function FindTestCaseInfo(ByVal inTest() As String, ByVal inTestCaseValue As String, ByRef outTestCaseName As String, ByRef outActivated As Boolean, ByRef outRowNo As Integer) As Boolean
        ' Find test case and get all info
        Dim intCountOcc As Integer = 0
        Dim intPos As Integer = 0

        For i As Integer = 0 To inTest.Count - 1
            intPos = inTest(i).IndexOf(inTestCaseValue)
            If intPos > -1 Then
                intCountOcc += 1
                If intCountOcc > 1 And Not IsCommentLine(inTest(i)) And inTest(i).Substring(intPos + inTestCaseValue.Length) = "]" Then
                    Dim strActivated As String = ""
                    If Not SplitAttribute(inTest(i + 1), "=", "", strActivated) Then
                        outRowNo = i + 1
                        Return False
                    End If
                    If Not SplitAttribute(inTest(i + 2), "=", "", outTestCaseName) Then
                        outRowNo = i + 2
                        Return False
                    End If
                    outActivated = CBool(strActivated)

                    Return True
                End If
            End If
        Next

        Return False
    End Function

    Private Function IsCommentLine(ByVal inLine As String) As Boolean
        Return (Mid(Trim(inLine), 1, 1) = ";")
    End Function

    Public Overrides Sub Clear()
        listTestSuites.Clear()
        intVerbose = 0
        strProjectName = ""
    End Sub

    Public Function MustSynchronize(ByRef inOtherObj As FileMng_UTIni) As Boolean
        If Me.strProjectName <> inOtherObj.strProjectName Then Return True
        If Me.listTestSuites.Count <> inOtherObj.listTestSuites.Count Then Return True
        For i As Integer = 0 To Me.listTestSuites.Count - 1
            If Me.listTestSuites(i).strName <> inOtherObj.listTestSuites(i).strName Then
                Return True
            End If
            If Me.listTestSuites(i).vettTestCases.Count <> inOtherObj.listTestSuites(i).vettTestCases.Count Then
                Return True
            End If

            For j As Integer = 0 To Me.listTestSuites(i).vettTestCases.Count - 1
                If Me.listTestSuites(i).vettTestCases(j).strName <> inOtherObj.listTestSuites(i).vettTestCases(j).strName Then
                    Return True
                End If
            Next

        Next

        Return False
    End Function

#End Region

#Region "Load File Main"

    Private Function GetListTestStructureFromMain(ByVal inTest() As String, ByVal inFirstBlocker As String, ByVal inSecondBlocker As String, ByVal inLastBlocker As String, ByRef outListTestStructure As List(Of TestStructure), ByRef outRowNo As Integer) As Boolean
        Dim blnEnd As Boolean = False
        Dim intCounterLine As Integer = 0

        For Each strLine As String In inTest
            Dim intPosition As Integer = strLine.IndexOf(inFirstBlocker)
            Dim intPositionSecondBlocker As Integer = strLine.IndexOf(inSecondBlocker)

            If intPosition > -1 And intPositionSecondBlocker > -1 Then
                Dim strLocalLine As String = ""
                intCounterLine += 2

                ' read all test structure
                While blnEnd = False
                    strLocalLine = inTest(intCounterLine)

                    If strLocalLine.Contains(inLastBlocker) Then
                        blnEnd = True
                    Else
                        If strLocalLine.Contains("{") Then
                            ' read all lines until "}"
                            Do While Not strLocalLine.Contains("}")
                                intCounterLine += 1
                                strLocalLine &= inTest(intCounterLine)
                            Loop

                            ' remove tabs and spaces
                            strLocalLine = CleanString(strLocalLine)
                            ' remove brackets and spaces
                            strLocalLine = Trim(Mid(strLocalLine, strLocalLine.IndexOf("{") + 2, strLocalLine.IndexOf("}") - 1))

                            Dim intFirstPos = strLocalLine.IndexOf(",")
                            Dim intLastPos = strLocalLine.LastIndexOf(",")

                            If intPosition > -1 Then
                                outListTestStructure.Add(New TestStructure(Trim(Mid(strLocalLine, 2, intFirstPos - 2)), Trim(Mid(strLocalLine, intLastPos + 2, strLocalLine.Length)), True))
                            Else
                                outRowNo = intCounterLine
                                Return False
                            End If
                        Else
                            outRowNo = intCounterLine
                            Return False
                        End If
                    End If
                    intCounterLine += 1
                End While

                Exit For
            End If

            intCounterLine += 1
        Next

        Return True
    End Function

    Public Overrides Function ReadSourceFile(ByRef inText() As String) As Boolean
        Try
            Dim blnRet As Boolean = True
            Dim intRowError As Integer = 0
            Dim listTestCasesAppo As New List(Of TestStructure)

            ' Load Suite info
            blnRet = GetListTestStructureFromMain(inText, "CU_SuiteInfo", "", "CU_SUITE_INFO_NULL", listTestCasesAppo, intRowError)
            If blnRet = False Then
                strErrorMsg = "Error to read suite structure" & vbCrLf & "Line = " & intRowError
                Return False
            End If

            For i = 0 To listTestCasesAppo.Count - 1
                Me.listTestSuites.Add(New TestSuite(listTestCasesAppo(i).strName, listTestCasesAppo(i).strValue, True))
            Next

            ' For each test suite load test cases info
            For i As Integer = 0 To Me.listTestSuites.Count - 1
                blnRet = GetListTestStructureFromMain(inText, "CU_TestInfo", Me.listTestSuites(i).strValue, "CU_TEST_INFO_NULL", Me.listTestSuites(i).vettTestCases, intRowError)
                If blnRet = False Then
                    strErrorMsg = "Error to read test case structure" & vbCrLf & "Line = " & intRowError
                    Return False
                End If
            Next

            Return True
        Catch ex As Exception
            strErrorMsg = "Error to read file Main.c"
            Return False
        End Try
    End Function

#End Region

#Region "Load File INI"

    Private Function GetListTestStructureFromINI(ByVal inTest() As String, ByRef outRowNo As Integer) As Boolean
        Dim intNumberTestSuites As Integer = 0
        Dim intCounterSuite As Integer = 0
        Dim i As Integer

        For i = 0 To inTest.Count - 1
            If inTest(i).IndexOf("suitenum") > -1 Then
                ' read suiteNum
                Dim strNumSuites As String = ""
                If Not SplitAttribute(inTest(i), "=", "", strNumSuites) Then
                    outRowNo = i
                    Return False
                End If
                intNumberTestSuites = CInt(strNumSuites)

                ' read projectName
                If Not SplitAttribute(inTest(i + 1), "=", "", Me.strProjectName) Then
                    outRowNo = i + 1
                    Return False
                End If

            ElseIf inTest(i).IndexOf("verbose") > -1 Then
                ' read verbose
                If Not SplitAttribute(inTest(i), "=", "", Me.intVerbose) Then
                    outRowNo = i
                    Return False
                End If

            ElseIf inTest(i).IndexOf("[SUITE") > -1 And Not IsCommentLine(inTest(i)) Then
                ' read test suite info and test cases
                i += 1
                Do While inTest(i) <> ""
                    If inTest(i).IndexOf("name") > -1 Then
                        Dim strNameSuite As String = ""
                        Dim strNameValue As String = inTest(i - 1).Replace("[", "").Replace("]", "")
                        Dim strActivated As String = ""
                        ' read test suite name
                        If Not SplitAttribute(inTest(i), "=", "", strNameSuite) Then
                            outRowNo = i
                            Return False
                        End If
                        ' read test suite active
                        If Not SplitAttribute(inTest(i + 1), "=", "", strActivated) Then
                            outRowNo = i + 1
                            Return False
                        End If
                        Me.listTestSuites.Add(New TestSuite(strNameSuite, strNameValue, CInt(strActivated)))
                    ElseIf inTest(i).IndexOf("TEST") > -1 Then
                        Dim strNameTestCase As String = ""
                        Dim strValueTestCase As String = ""
                        Dim blnActivated As String = True
                        ' read test case name
                        If Not SplitAttribute(inTest(i), "=", "", strValueTestCase) Then
                            outRowNo = i
                            Return False
                        End If
                        ' finf test case and read all info
                        If Not FindTestCaseInfo(inTest, strValueTestCase, strNameTestCase, blnActivated, outRowNo) Then
                            Return False
                        End If
                        Me.listTestSuites(Me.listTestSuites.Count - 1).vettTestCases.Add(New TestStructure(strNameTestCase, strValueTestCase, blnActivated))
                    End If
                    i += 1
                Loop
                intCounterSuite += 1
            End If

            If intNumberTestSuites <> 0 AndAlso intCounterSuite >= intNumberTestSuites Then
                ' read all test cases
                Exit For
            End If
        Next

        Return True
    End Function

    Public Overrides Function ReadFile(ByRef inText() As String) As Boolean
        Try
            Dim blnRet As Boolean = True
            Dim intRowError As Integer = 0

            ' read all ini structure
            blnRet = GetListTestStructureFromINI(inText, intRowError)
            If blnRet = False Then
                strErrorMsg = "Error to read INI structure" & vbCrLf & "Line = " & intRowError
                Return False
            End If

            Return True
        Catch ex As Exception
            strErrorMsg = "Error to read file INI"
            Return False
        End Try
    End Function

#End Region

#Region "Save File INI"

    Public Overrides Function SaveFile(ByVal inFilePath As String) As Boolean
        Try
            Dim strFileContent As String = ""
            Call GenerateFile(strFileContent)

            Dim oWriter As New IO.StreamWriter(inFilePath)

            oWriter.WriteLine(strFileContent)
            oWriter.Close()

            oWriter = Nothing

            Return True
        Catch ex As Exception
            strErrorMsg = "Error to save file INI"
            Return False
        End Try
    End Function

#End Region

#Region "Generate file INI"

    Public Overrides Function GenerateFile(ByRef outFile As String) As Boolean
        Dim intIndex As Integer = 1
        Dim strBuilder As New System.Text.StringBuilder

        ' Header
        strBuilder.Append("[TEST]" & vbCrLf)
        strBuilder.Append("suitenum=" & Me.listTestSuites.Count & vbCrLf)
        strBuilder.Append("name=" & Me.strProjectName & vbCrLf)
        strBuilder.Append("verbose=" & Me.intVerbose & vbCrLf)
        strBuilder.Append(vbCrLf)

        ' Suites
        For Each objTestSuite As TestSuite In Me.listTestSuites
            strBuilder.Append(String.Format(";--- {0} ---", objTestSuite.strName) & vbCrLf & vbCrLf)
            strBuilder.Append(String.Format("[SUITE{0}]", Format(intIndex, "000")) & vbCrLf)
            strBuilder.Append("name=" & objTestSuite.strName & vbCrLf)
            strBuilder.Append("active=" & IIf(objTestSuite.blnActivated, "1", "0") & vbCrLf)
            strBuilder.Append("testnum=" & objTestSuite.vettTestCases.Count & vbCrLf)
            For i As Integer = 1 To objTestSuite.vettTestCases.Count
                strBuilder.Append(String.Format("T0{0}=TEST{1}{2}", Format(i, "00"), intIndex, Format(i, "00")) & vbCrLf)
            Next
            intIndex += 1
            strBuilder.Append(vbCrLf)
        Next
        strBuilder.Append(vbCrLf)

        ' TestCases
        For i As Integer = 0 To Me.listTestSuites.Count - 1
            intIndex = 1
            strBuilder.Append(String.Format(";--- {0} ---", Me.listTestSuites(i).strName) & vbCrLf & vbCrLf)
            For Each objTestCase As TestStructure In Me.listTestSuites(i).vettTestCases
                strBuilder.Append(String.Format("[TEST{0}{1}]", i + 1, Format(intIndex, "00")) & vbCrLf)
                strBuilder.Append("active=" & IIf(objTestCase.blnActivated, "1", "0") & vbCrLf)
                strBuilder.Append("name=" & objTestCase.strName & vbCrLf)
                strBuilder.Append(vbCrLf)
                intIndex += 1
            Next
            strBuilder.Append(vbCrLf)
        Next

        outFile = strBuilder.ToString

        Return True
    End Function

#End Region

End Class
